package com.agan.limit.aop;

import com.agan.limit.condition.LimitAspectCondition;
import com.agan.limit.exception.LimiterException;
import com.agan.limit.manager.LimiterManager;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 限流切面处理
 *
 * @author weicj
 * @since 2025.01.24
 */

@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true) //使用CGLIB代理
@Conditional(LimitAspectCondition.class)
public class LimitAspect {

    @Resource
    private LimiterManager limiterManager;

    @Before("@annotation(com.agan.limit.aop.Limit)")
    public void before(JoinPoint joinPoint){

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        Method method = signature.getMethod();

        Limit limit = method.getAnnotation(Limit.class);

        if(limit != null){
            if(!limiterManager.tryAccess(limit)){
                throw new LimiterException(limit.msg());
            }
        }
    }
}
